#!/usr/bin/python

import os
import sys
import subprocess
from errors import GitCommandError as GitError
import time

VSERSION = (1, 0.0)
KWARGS = ('command', 'target', 'dir')

class GitArgsParser(object):
    def __init__( self, args_need_parsed ):
        self.__command_key = 'command'
        self.__target_key = 'target'
        self.__dir_key = 'dir'
        self.__args = args_need_parsed
        self.__result = ['git']
        
        self._parser()

    def is_parsed( self ):
        if 0==len(self.__result):
            return False
        return True

    def get_command( self ):
        if 0==len(self.__result):
            return None
        return self.__result

    def get_dir( self ):
        if self.__dir_key in self.__args:
            return self.__args[self.__dir_key]
        else:
            return None

    def _parser( self ):
        if False==isinstance( self.__args, dict ):
            raise GitError( None, 'fatal: excute git command failed, the args is not dict struct' )
        if not self.__command_key in self.__args:
            raise GitError( None, 'fatal: excute git command failed, the command  is not exists')
        else:
            split = self.__args[self.__command_key].split()
            for item in split:
                self.__result.append( item )

        if self.__target_key in self.__args:
            self.__result.append( self.__args[self.__target_key] )
        

class Git(object):
    """
    The Git class to excute the command object
    """
    def __init__( self, work_dir=None ):
        super(Git, self).__init__()
        if None==work_dir:
            self.__work_dir = os.getcwd()
        else:
            self.__work_dir = work_dir

    def run(self, kwargs, fun=None ):
        return self._call_process( fun, kwargs )

    def _call_process( self, fun, kwargs ):
        parser = GitArgsParser( kwargs )
        if False==parser.is_parsed():
            raise GitError( None, 'fatal: git parser args failed')
        command = parser.get_command()
        if None==command:
            raise GitError( None, 'fatal: git parser command failed' )
        
        result = self._execute( command, parser.get_dir() )
        if None!=result and None!=fun:
            ret = fun( ret )
            if None!=ret:
                return ret
            else:
                return ''
        elif None!=result and None==fun:
            return result[0]

        return ''
        
    def _execute( self, command, cwd=None, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE ):
        if None==cwd:
            cwd = self.__work_dir

        try:
            print 'popen command : ', command
            proc = subprocess.Popen( command, cwd=cwd, stdin=stdin, stderr=stderr, stdout=stdout )

            status = proc.wait()
            #stdout_value = proc.stdout.readlines()
            stdout_value = ''
            #stderr_value = proc.stderr.readlines()
            stderr_value = ''
            #print 'result string : ', stdout_value
        except OSError, e:
            print >>sys.stderr, 'fatal: popen to excute the command failed'
            return None
        finally:
            #proc.stdout.close()
            #proc.stderr.close()
            pass

        if 0!=status:
            raise GitError( None, 'fatal: wait for the popen excute failed')

        return [stdout_value, stderr_value]


